{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 简介"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 网格的数据结构\n",
    "* 网格类型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## IntervalMesh"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## TirangleMesh"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 三角形网格的数据结构"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np \n",
    "import matplotlib.pyplot as plt \n",
    "from fealpy.mesh.TriangleMesh import TriangleMesh\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "网格是有限元算法的基础, 最少需要两个二维数组来存储网格的信息:\n",
    "\n",
    "* 网格节点坐标数组 `node`:\n",
    "    + $NN\\times 2$ 的二维数组\n",
    "    + `node[i, 0]` 和 `node[i, 1]` 分别存储第 $i$ 个网格节点的 $x$ 和 $y$ 坐标\n",
    "* 单元顶点编号数组 `cell`:\n",
    "    + $NC\\times 3$ 的二维数组\n",
    "    + `cell[i, 0]`, `cell[i, 1]` 和 `cell[i, 2]` 分别存储第 $i$ 个单元三个顶点的全局编号(即 `node` 中的行号)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "node = np.array(\n",
    "    [(0.0, 0.0),\n",
    "     (1.0, 0.0),\n",
    "     (1.0, 1.0),\n",
    "     (0.0, 1.0)], dtype=np.float)\n",
    "cell = np.array([\n",
    "        (1, 2, 0), \n",
    "        (3, 0, 2)], dtype=np.int)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fealpy.mesh.TriangleMesh import TriangleMesh\n",
    "import matplotlib.pyplot as plt \n",
    "%matplotlib inline\n",
    "tmesh = TriangleMesh(node, cell)\n",
    "fig, axes = plt.subplots(1, 3)\n",
    "tmesh.add_plot(axes[0], cellcolor='w')\n",
    "tmesh.find_node(axes[0], showindex=True, markersize=25, fontsize=12)\n",
    "tmesh.find_cell(axes[0], showindex=True, markersize=100, fontsize=12)\n",
    "axes[0].set_title('mesh')\n",
    "\n",
    "for ax in axes.reshape(-1)[1:]:\n",
    "    ax.axis('tight')\n",
    "    ax.axis('off')\n",
    "axes[1].table(cellText=node, rowLabels=['0:', '1:', '2:', '3:'], loc='center')\n",
    "axes[1].set_title('node', y=0.3)\n",
    "axes[2].table(cellText=cell, rowLabels=['0:', '1:'], loc='center')\n",
    "axes[2].set_title('cell', y=0.35)\n",
    "plt.tight_layout(pad=1, w_pad=1, h_pad=1.0)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "除了上述两个基本数组之外, 有限元方法中还需要更多的网格数据, 如:\n",
    "\n",
    "* 边数组 `edge`\n",
    "    + 二维 $NE\\times 2$ 数组 \n",
    "    + `edge[i, 0]` 和 `edge[i, 1]` 分别存储第 $i$ 条边的起点和终点的全局编号(即对应 `node` 数组中的行号)\n",
    "    + 如果第 $i$ 条边是边界边, 则规定从 `edge[i, 0]` 看向 `edge[i, 1]`, 网格离散区域一定在左手边\n",
    "* 边与单元的相邻关系数组 `edge2cell`\n",
    "    + 二维 $NE \\times 4 $ 的数组\n",
    "    + `edge2cell[i, 0]` 和 `edge2cell[i, 1]` 分别存储第 $i$ 条边左右两个单元的全局编号(即对应 `cell` 数组中的行号)\n",
    "    + `edge2cell[i, 2]` 和 `edge2cell[i, 3]` 分别存储第 $i$ 条边在左右两个单元中的局部编号\n",
    "    + 如果是边界边, 则\n",
    "        - `edge2cell[i, 0] = edge2cell[i, 1]` \n",
    "        - `edge2cell[i, 2] = edge2cell[i, 3]`\n",
    "        \n",
    "**注: `edge` 和 `edge2cell` 可以从 `cell` 中构造出来.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "stotalEdge [[0 2]\n",
      " [0 1]\n",
      " [1 2]\n",
      " [0 2]\n",
      " [2 3]\n",
      " [0 3]]\n",
      "i0 [1 0 5 2 4]\n",
      "j [1 0 3 1 4 2]\n",
      "1 [0 1 2 3 4 5]\n",
      "i1 [1 3 5 2 4]\n",
      "[[0 1]\n",
      " [2 0]\n",
      " [3 0]\n",
      " [1 2]\n",
      " [2 3]]\n",
      "[[0 0 1 1]\n",
      " [0 1 0 0]\n",
      " [1 1 2 2]\n",
      " [0 0 2 2]\n",
      " [1 1 1 1]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from fealpy.mesh.mesh_tools import unique_row\n",
    "\n",
    "node =np.array(\n",
    "    [(0.0, 0.0),\n",
    "     (1.0, 0.0),\n",
    "     (1.0, 1.0),\n",
    "     (0.0, 1.0)], dtype=np.float)\n",
    "\n",
    "cell = np.array([\n",
    "        (1, 2, 0), \n",
    "        (3, 0, 2)], dtype=np.int)\n",
    "localEdge = np.array(\n",
    "    [(1, 2),\n",
    "     (2, 0),\n",
    "     (0, 1)], dtype=np.int)\n",
    "\n",
    "totalEdge = cell[:, localEdge]\n",
    "totalEdge = totalEdge.reshape(-1, 2)\n",
    "stotalEdge = np.sort(totalEdge, axis=1)\n",
    "print('stotalEdge',stotalEdge)\n",
    "uedge, i0, j = unique_row(stotalEdge)\n",
    "NE = i0.shape[0]\n",
    "print('i0',i0)\n",
    "print('j',j)\n",
    "i1 = np.zeros(NE, dtype=np.int) \n",
    "NC = cell.shape[0]\n",
    "i1[j] = np.arange(3*NC)\n",
    "print('1',np.arange(3*NC))\n",
    "print('i1',i1)\n",
    "edge2cell = np.zeros((NE, 4), dtype=np.int)\n",
    "t0 = i0//3\n",
    "t1 = i1//3\n",
    "k0 = i0%3\n",
    "k1 = i1%3\n",
    "edge2cell[:, 0] = t0\n",
    "edge2cell[:, 1] = t1\n",
    "edge2cell[:, 2] = k0\n",
    "edge2cell[:, 3] = k1\n",
    "\n",
    "edge = totalEdge[i0]\n",
    "print(edge)\n",
    "print(edge2cell)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n54nIo2I9LfeoiPzevqOeKCsigkWLFmHixImBrP/EiROYNm0ali1bhoICVx97QvDxCUtcPweJS2qw\nHm7XX1XPh3Vq8S4RKXe5DoVVqLXNxxqo6suqeg2sO97/G8DDPm4DYN0juB/A1fa23A7gWXE8wp2o\nPUVFRdi/f//Zn2tqalBU1OZjsrLW2NiIadOmYdasWZg8eXIgbYS9TUEKc1vCbCuMz4FXiUtqqrpT\nVc/YPwqsBDUozSJtWQ1gUmuPNRCRi0Vkkn1t7QyAE7AeFeEbVT2lqneq6vv2z+thDXL5nJ/tkNlG\njRqF3bt3Y9++fTh9+jTWrFmDSZOCeyrL7NmzMWzYMMyfPz+wNsLepiCFuS1hthXG58CzKEepeJ0A\nPAjrUefNsK6DOR9T/i4cj6QH8CSAhY6f5wB4yf7/KAC/hvU4jAMA1sJ6WGFv+/XUo8k3ARhiL3MT\ngN+06E8TgIFZblMvWI+sKI56/3KK/wTHSLbKykotLi7WwYMH65IlS1RVdeHChbp27dqz88CHkW+v\nvvqqdujQQUtLS7WsrEzLy8u1srLS1zZSWtumFu1EHoN0UxTxaastv9vI8HMQ2b5PbEUR+4F2XwTw\nFwCWqmpTtD3yTkQ6wnqy7B9V9ZtR94fijxUrWFHErVyJT+JOP6bYfxS8Buvx338bdX+8spPzalgP\nxrst4u4QESWaCQWNO8LbNbW4eAzW/XPXJvlok4goDhKV1ESkJ4CxsG6argcwDtZzlxL57CUReQjA\nEAD/Q6176Igykp+f3ywiGZ9pyc/Ph3VSIDhhtGG34+ugrSAwPtFJzjU1ET0E667pP+XlIS8vD927\nd9eysrLmESNGxP5D/sYbb3T48htv5KWqsYl1n9xeAA2wBpoA1kjOear6TARdTCQRaQYwWFXfFZFV\nAN5X1YVR9ytovGbDa2pu5Ux8ohyl4moC9DSg5QUF54waSoof//jHermIngZUEzB6KykTHCNPAayC\nVfYs8n6FsN2qqjp79my9+OKLtaSkRNOBj6PrLr/8cr3sssv0nnvuCaSN9rYJCfj9YXwi3PdRNu5m\n+p6IlhcU6PVf/ao2NjZmtPPjoqamRgsLC5v7fvazWpKfr98DmjQG+9SECdZtHTmb1F555RWtrq4O\n5UszrIK57W1T1F+amUyMT3T7PjGjH4/Om4c7n3kGv9i4EXl5eVF3J2O1tbUYPXq0lpWV6XsHDmDK\n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\npEZERMZgUiMiImMwqRERkTGY1IiIyBhMakREZIzE3HzdpUuXDxoaGnpF3Q8/5OfnH6ivr2+rpl0i\nMT7hcru/8/PzmxsaGjL+I9bt/CEvk/Px8SKMNux2Io1PYm6+FhFjnkghIlBVox5Tz/iEy+3+trcp\nsPkjWCan4+NFGG042oksPjz96KM5c+agV69euOKKK6LuCrXC1Phs2LABQ4YMQXFxMZYuXRr48l7a\n87LvTYlXtvGJW1uxj4uqJmKyuhpvr7zyilZXV2tJSUna+extiXyf+jkxPtHs76amJh00aJDu3btX\nT58+raWlpbpz5862tulT2lre7fzp2lBte99nsUzkMUg3+RUfN9pry6/f0fZ+j6KOD4/UfHTVVVfh\nwgsvjLob1AYT41NVVYXLLrsM/fv3R6dOnTB9+nQ8//zzgS3vtT0v+96EeGUbnzi2Ffe4MKkRJVht\nbS369u179uc+ffqgpqYGixYtwrp16zwtX1tb69v8uS7b+GTbVi7GJjGjH4koMyKCRYsWRd0NagPj\nEyweqRElWFFREfbv33/255qaGhQVFQW2fLbt5Zow9xdjY2FS81nqYiXFk2nxGTVqFHbv3o19+/bh\n9OnTWLNmDSZNmhTY8tm052XfJz1e2cYnrm3FOi5RjlJxMyEBo+tmzJihhYWFet5552nfvn318ccf\nb3U+JGD0ltuJ8Yluf1dWVmpxcbEOHjxYlyxZoqqqCxcu1LVr17bcpla1trzb+dtbpq19n8Uykccg\n3eRnfNxoKzZ+ttHe71HU8eHN1xGI+ubEIDA+4eLN17kdHy948zUREVHCMKkREZExEjOkPz8/v1lE\njEjC+fn5zVH3wW+MT7jc7u/8/HyIZH5GyO38IS+T8/HxIow27HYijQ+vqUUg6nPOQWB8wsVrarkd\nHy94TY2IiChhmNR8FGY1bnLn448/RkVFBcrLy1FSUoLFixdH3SVf+FEx3e3n1kubXn43TPh9CrOi\nfU1NDcaOHYvhw4ejpKQEy5cvD6ytWMcmyvsJ3EyI+X1QmVbjVo3+Po4gprjHR1X15MmTqqra2Nio\nFRUVunXr1lbnS0J8Uvvb5ZMHPsVtlf50bbptI8tlIo9Busmv+LhRV1en1dXVqqp6/PhxLS4uDqRK\nf4ZPA4hs3/NIzSdhVuMmb7p27QrAOmprbGwM5aJ50LKtmO7lc+u2TS9tmPL7FGZF+969e6OsrAwA\n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\nAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f9419cd1908>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from fealpy.mesh.TriangleMesh import TriangleMesh\n",
    "import matplotlib.pyplot as plt \n",
    "%matplotlib inline\n",
    "tmesh = TriangleMesh(node, cell)\n",
    "fig, axes = plt.subplots(2, 4)\n",
    "tmesh.add_plot(axes[0, 0], cellcolor='w')\n",
    "tmesh.find_node(axes[0, 0], showindex=True, markersize=25, fontsize=12)\n",
    "tmesh.find_cell(axes[0, 0], showindex=True, markersize=100, fontsize=12)\n",
    "axes[0, 0].set_title('mesh')\n",
    "\n",
    "for ax in axes.reshape(-1)[1:]:\n",
    "    ax.axis('tight')\n",
    "    ax.axis('off')\n",
    "axes[0, 1].table(cellText=cell, rowLabels=['0:', '1:'], loc='center')\n",
    "axes[0, 1].set_title('cell', y=0.6)\n",
    "axes[0, 2].table(cellText=totalEdge, rowLabels=['0:', '1:', '2:', '3:', '4:', '5:'], loc='center')\n",
    "axes[0, 2].set_title('totalEdge', y=0.85)\n",
    "axes[0, 3].table(cellText=np.sort(totalEdge, axis=1), rowLabels=['0:', '1:', '2:', '3:', '4:', '5:'], loc='center')\n",
    "axes[0, 3].set_title('Sorted totalEdge', y=0.85)\n",
    "axes[1, 0].table(cellText=i0.reshape(-1,1),  loc='center')\n",
    "axes[1, 0].set_title('i0', y=0.85)\n",
    "axes[1, 1].table(cellText=i1.reshape(-1,1),  loc='center')\n",
    "axes[1, 1].set_title('i1', y=0.85)\n",
    "axes[1, 2].table(cellText=edge2cell,  rowLabels=['0:', '1:', '2:', '3:', '4:'], loc='center')\n",
    "axes[1, 2].set_title('edge2cell', y=0.85)\n",
    "axes[1, 3].table(cellText=edge,  rowLabels=['0:', '1:', '2:', '3:', '4:'], loc='center')\n",
    "axes[1, 3].set_title('edge', y=0.85)\n",
    "plt.tight_layout(pad=1, w_pad=1, h_pad=1.0)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 下面给出网格的数据结构示意图："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f801911c6d8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from fealpy.mesh.TriangleMesh import TriangleMesh\n",
    "import matplotlib.pyplot as plt \n",
    "%matplotlib inline\n",
    "node = np.array(\n",
    "    [(0.0, 0.0),\n",
    "     (1.0, 0.0),\n",
    "     (1.0, 1.0),\n",
    "     (0.0, 1.0)], dtype=np.float)\n",
    "cell = np.array([\n",
    "        (1, 2, 0), \n",
    "        (3, 0, 2)], dtype=np.int)\n",
    "tmesh = TriangleMesh(node, cell) # 三角形网格实例\n",
    "fig, axes = plt.subplots(2, 3)\n",
    "tmesh.add_plot(axes[0, 0], cellcolor='w')\n",
    "tmesh.find_node(axes[0, 0], showindex=True, markersize=25, fontsize=12)\n",
    "tmesh.find_edge(axes[0, 0], showindex=True, markersize=50, fontsize=12)\n",
    "tmesh.find_cell(axes[0, 0], showindex=True, markersize=100, fontsize=12)\n",
    "axes[0, 0].set_title('mesh')\n",
    "\n",
    "for ax in axes.reshape(-1)[1:]:\n",
    "    ax.axis('tight')\n",
    "    ax.axis('off')\n",
    "axes[0, 1].table(cellText=node, rowLabels=['0:', '1:', '2:', '3:'], loc='center')\n",
    "axes[0, 1].set_title('node')\n",
    "axes[0, 2].table(cellText=cell, rowLabels=['0:', '1:'], loc='center')\n",
    "axes[0, 2].set_title('cell')\n",
    "axes[1, 0].table(cellText=tmesh.ds.edge, rowLabels=['0:', '1:', '2:', '3:', '4:'],  loc='center')\n",
    "axes[1, 0].set_title('edge')\n",
    "axes[1, 1].table(cellText=tmesh.ds.edge2cell, rowLabels=['0:', '1:', '2:', '3:', '4:'],  loc='center')\n",
    "axes[1, 1].set_title('edge2cell')\n",
    "axes[1, 2].table(cellText=tmesh.ds.cell_to_edge(), rowLabels=['0:', '1:'],  loc='center')\n",
    "axes[1, 2].set_title('cell2edge')\n",
    "plt.tight_layout(pad=1, w_pad=1, h_pad=1.0)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\npf8HHC4oTOk6dJEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f80563b0a58>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "tmesh = TriangleMesh(node, cell)\n",
    "tmesh.uniform_refine(0)\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "tmesh.add_plot(axes)\n",
    "tmesh.add_plot(axes, cellcolor='w')\n",
    "tmesh.find_node(axes, showindex=True, markersize=25, fontsize=12)\n",
    "tmesh.find_edge(axes, showindex=True, markersize=50, fontsize=12)\n",
    "tmesh.find_cell(axes, showindex=True, markersize=100, fontsize=12)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 单元所对应的网格点的对应关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 0)\tTrue\n",
      "  (0, 1)\tTrue\n",
      "  (0, 2)\tTrue\n",
      "  (1, 0)\tTrue\n",
      "  (1, 2)\tTrue\n",
      "  (1, 3)\tTrue\n"
     ]
    }
   ],
   "source": [
    "print(tmesh.ds.cell_to_node())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 单元所对应的三条边的对应关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 0 3]\n",
      " [1 4 2]]\n"
     ]
    }
   ],
   "source": [
    "print(tmesh.ds.cell_to_edge())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 单元三条边所对应的邻居单元"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 单元所对应的邻居单元的全局编号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 0 0]\n",
      " [0 1 1]]\n"
     ]
    }
   ],
   "source": [
    "print(tmesh.ds.cell_to_cell())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "operands could not be broadcast together with shapes (5,2) (2,5) ",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-45-0ae2e874bf2a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtmesh\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mds\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medge_to_edge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m~/repository/fealpy/doc/chinese-doc/fealpy/mesh/Mesh2d.py\u001b[0m in \u001b[0;36medge_to_edge\u001b[0;34m(self, sparse)\u001b[0m\n\u001b[1;32m    382\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0medge_to_edge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msparse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    383\u001b[0m         \u001b[0medge2node\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medge_to_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 384\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0medge2node\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0medge2node\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtranspose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    385\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    386\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0medge_to_cell\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msparse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mValueError\u001b[0m: operands could not be broadcast together with shapes (5,2) (2,5) "
     ]
    }
   ],
   "source": [
    "print(tmesh.ds.edge_to_edge())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 网格节点与它相邻边的全局编号的对应关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 0)\tTrue\n",
      "  (0, 1)\tTrue\n",
      "  (0, 2)\tTrue\n",
      "  (1, 0)\tTrue\n",
      "  (1, 3)\tTrue\n",
      "  (2, 1)\tTrue\n",
      "  (2, 3)\tTrue\n",
      "  (2, 4)\tTrue\n",
      "  (3, 2)\tTrue\n",
      "  (3, 4)\tTrue\n"
     ]
    }
   ],
   "source": [
    "print(tmesh.ds.node_to_edge())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 网格节点的邻居节点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 1)\tTrue\n",
      "  (0, 2)\tTrue\n",
      "  (0, 3)\tTrue\n",
      "  (1, 0)\tTrue\n",
      "  (1, 2)\tTrue\n",
      "  (2, 0)\tTrue\n",
      "  (2, 1)\tTrue\n",
      "  (2, 3)\tTrue\n",
      "  (3, 0)\tTrue\n",
      "  (3, 2)\tTrue\n"
     ]
    }
   ],
   "source": [
    "print(tmesh.ds.node_to_node())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 单元节点对应的单元编号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 0)\tTrue\n",
      "  (0, 1)\tTrue\n",
      "  (1, 0)\tTrue\n",
      "  (2, 0)\tTrue\n",
      "  (2, 1)\tTrue\n",
      "  (3, 1)\tTrue\n"
     ]
    }
   ],
   "source": [
    "print(tmesh.ds.node_to_cell())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 其它三角形网格的生成"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "方形区域的一致的三角形网格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "__init__() got an unexpected keyword argument 'dtype'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-87-63bb5cf37c34>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mfealpy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmesh\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimple_mesh_generator\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0msquaremesh\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmesh\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msquaremesh\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0mfig\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0maxes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfig\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgca\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mmesh\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_plot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/repository/fealpy/doc/chinese-doc/fealpy/mesh/simple_mesh_generator.py\u001b[0m in \u001b[0;36msquaremesh\u001b[0;34m(x0, x1, y0, y1, r, dtype)\u001b[0m\n\u001b[1;32m     17\u001b[0m     node = np.array([\n\u001b[1;32m     18\u001b[0m         \u001b[0;34m[\u001b[0m\u001b[0mx0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m         \u001b[0;34m[\u001b[0m\u001b[0mx1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     20\u001b[0m         \u001b[0;34m[\u001b[0m\u001b[0mx1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     21\u001b[0m         [x0, x1]], dtype=np.float)\n",
      "\u001b[0;31mTypeError\u001b[0m: __init__() got an unexpected keyword argument 'dtype'"
     ]
    }
   ],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import squaremesh\n",
    "mesh = squaremesh(0, 1, 0, 1, r=4)\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import rectangledomainmesh\n",
    "box = [-1, 1, -1, 1]\n",
    "mesh = rectangledomainmesh(box, nx=10, ny=10, meshtype='tri')\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import unitcircledomainmesh\n",
    "mesh = unitcircledomainmesh(0.1, meshtype='tri')\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import triangle\n",
    "mesh = triangle([0,1,0,1], 0.125, meshtype='tri')\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import fishbone\n",
    "mesh = fishbone([0,1,0,1], 10)\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import cross_mesh\n",
    "mesh = cross_mesh([0,1,0,1], 10)\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import rice_mesh\n",
    "mesh = rice_mesh([0,1,0,1], 10)\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import nonuniform_mesh\n",
    "mesh = nonuniform_mesh([0,1,0,1], 6)\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from fealpy.mesh.simple_mesh_generator import uncross_mesh\n",
    "mesh = uncross_mesh(box, n=10, r=\"1\")\n",
    "fig = plt.figure()\n",
    "axes = fig.gca()\n",
    "mesh.add_plot(axes)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
<<<<<<< HEAD
   "version": "3.6.1"
||||||| merged common ancestors
   "version": "3.5.2"
=======
   "version": "3.6.6"
>>>>>>> bfdfd70078ea8e3fb9846e87d9b2c474668f4d5b
  },
  "latex_envs": {
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 0
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
